<?php
/**
 * Coupons plugin class
 *
 * Main class for all Coupon manipulations
 *
 * @access 	public
 * @author 	Rob/Valentin
 * @copyright	ResMania 2009 all rights reserved.
 * @version	1.0
 * @link	http://developer.resmania.com/api
 * @since  	08-2009
 */
class RM_Plugin_Coupons extends RM_Plugin implements RM_Discounts_Plugin_Interface {
    /**
     * Save selected discounts to the database from user end reservation process
     *
     * @abstract
     * @param RM_Reservation_Row $detail
     * @param RM_Reservation_Details_Row $detailRow
     * @return bool
     */
    public function save(RM_Reservation_Details $detail, RM_Reservation_Details_Row $detailRow){
        if (RM_Environment::getConnector()->getModule() == 'admin') {
            return true;
        }

        $summaryModel = new RM_ReservationSummary();
        $userCouponsModel = new RM_UserCoupons();

        $coupons = $this->get($detail);
        foreach ($coupons as $coupon) {
            $summaryModel->insert(array(
                'row_id' => $coupon->id,
                'type' => self::SUMMARY_TYPE,
                'reservation_id' => null,
                'reservation_detail_id' => $detailRow->id,
                'total_amount' => -$coupon->calculate($detail),
                'name' => $coupon->getName()
            ));

            $userCoupon = $userCouponsModel->createRow();
            $userCoupon->user_id = RM_Reservation_Manager::getInstance()->getUser()->id;
            $userCoupon->coupon_id = $coupon->id;
            $userCoupon->save();

            $coupon->used++;
            $coupon->save();
        }

        $this->clearSelected();
    }

    /**
     * Returns extra HTML for a summary reservation page to present current discount plugin
     *
     * @abstract
     * @param RM_Reservation_Details $detail
     * @return void
     */
    public function getSummary(RM_Reservation_Details $detail){        
        $html = <<<EOD
%s: <input type="text" id="couponCode_%d" value=""/><input type="button" value="%s" onclick="applyCouponCode(%d)"/><input type="button" value="%s" onclick="deleteCouponCode(%d)"/>
<script type="text/javascript">
function deleteCouponCode(unitID){
    Ext.Ajax.request({
        url: RM.Common.AssembleURL({
            controller : 'Coupons',
            action: 'deleteJson'
        }),
        params: {
            unitID: unitID,
            code: document.getElementById('couponCode_'+unitID).value
        },
        success: function(responseObject) {
            var response = Ext.util.JSON.decode(responseObject.responseText);
            if (response.success == false) {
                alert(response.error);
            } else {
                window.location.reload();
            }
        },
        failure: function() {
            alert('%s');
        }
    });
}

function applyCouponCode(unitID){
    Ext.Ajax.request({
        url: RM.Common.AssembleURL({
            controller : 'Coupons',
            action: 'applyJson'
        }),
        params: {
            unitID: unitID,
            code: document.getElementById('couponCode_'+unitID).value
        },
        success: function(responseObject) {
            var response = Ext.util.JSON.decode(responseObject.responseText);
            if (response.success == false) {
                alert(response.error);
            } else {
                window.location.reload();
            }
        },
        failure: function() {
            alert('%s');
        }
    });
}
</script>
EOD;
        $translate = RM_Environment::getInstance()->getTranslation(RM_Environment::TRANSLATE_MAIN);

        return sprintf($html,
            $translate->_('User.Coupons.Summary', 'CouponCode'),
            $detail->getUnit()->getId(),
            $translate->_('User.Coupons.Summary', 'Apply'),
            $detail->getUnit()->getId(),
            $translate->_('User.Coupons.Summary', 'Delete'),
            $detail->getUnit()->getId(),
            $translate->_('User.Coupons.Summary', 'LostConnection'),
            $translate->_('User.Coupons.Summary', 'LostConnection')
        );
    }

    /**
     * Get all discount object that are applied to current unit in the current reservation
     *
     * @abstract
     * @param RM_Reservation_Details $detail
     * @return array
     */
    public function get(RM_Reservation_Details $detail){
        if (RM_Environment::getConnector()->getModule() == 'admin') {
            return array();
        }

        //we are on the user end - we need to show only coupons that are already selected by user
        $selectedCouponIDs = $this->getSelected($detail->getUnit());
        $model = new RM_Coupons();
        $result = array();
        foreach ($selectedCouponIDs as $ID) {
            $coupon = $model->find($ID)->current();
            $user = RM_Reservation_Manager::getInstance()->getUser();

            //we need to recheck if actual user is in session, cause use could add coupon on
            //the cart page without actual login in to the system
            if ($user == null || $user->isGuest() || $coupon->isUsedBy($user) == false) {
                $result[] = $coupon;
            }
        }
        return $result;
    }

    public function clearSelected(){
        if (isset($_SESSION['RM_Coupons'])){
            unset($_SESSION['RM_Coupons']);
        }
        return true;
    }

    /**
     * Returns already selected coupons
     *
     * @param RM_Unit_Row $unit
     * @return array
     */
    public function getSelected(RM_Unit_Row $unit){        
        if (isset($_SESSION['RM_Coupons']) == false) {
            return array();
        }

        if (isset($_SESSION['RM_Coupons']['coupons']) == false) {
            return array();
        }

        if (isset($_SESSION['RM_Coupons']['coupons'][$unit->getId()]) == false) {
            return array();
        }
        
        return $_SESSION['RM_Coupons']['coupons'][$unit->getId()];
    }

    public function deleteSelected(RM_Unit_Row $unit, RM_Coupons_Row $coupon){
        if (isset($_SESSION['RM_Coupons']) == false) {
            return false;
        }

        if (isset($_SESSION['RM_Coupons']['coupons']) == false) {
            return false;
        }

        if (isset($_SESSION['RM_Coupons']['coupons'][$unit->getId()]) == false) {
            return false;
        }

        foreach ($_SESSION['RM_Coupons']['coupons'][$unit->getId()] as $key => $couponID) {
            if ($couponID == $coupon->id) {
                unset($_SESSION['RM_Coupons']['coupons'][$unit->getId()][$key]);
                return true;
            }
        }

        return false;
    }

    /**
     * Save selected coupon internally to show it on the UI
     *
     * @param RM_Unit_Row $unit
     * @param RM_Coupons_Row $coupon
     * @return bool
     */
    public function saveSelected(RM_Unit_Row $unit, RM_Coupons_Row $coupon){
        if (isset($_SESSION['RM_Coupons']) == false) {
            $_SESSION['RM_Coupons'] = array();
        }

        if (isset($_SESSION['RM_Coupons']['coupons']) == false) {
            $_SESSION['RM_Coupons']['coupons'] = array();
        }

        if (isset($_SESSION['RM_Coupons']['coupons'][$unit->getId()]) == false) {
            $_SESSION['RM_Coupons']['coupons'][$unit->getId()] = array();
        }

        foreach ($_SESSION['RM_Coupons']['coupons'][$unit->getId()] as $selectedCoupon) {
            if ($coupon->id == $selectedCoupon) {
                return false;
            }
        }
        $_SESSION['RM_Coupons']['coupons'][$unit->getId()][] = $coupon->id;
        return true;
    }

    /**
     * Recalculate all for reservation, after some of the unit details has been changed
     *
     * @param RM_Reservation_Row $reservation
     * @return bool
     */
    function recalculate(RM_Reservation_Row $reservation){
        $summaryModel = new RM_ReservationSummary();
        $couponModel = new RM_Coupons();
        $details = $reservation->getDetails();
        foreach ($details as $detail) {
            $summaryRows = $summaryModel->fetchByReservationDetail($detail);
            foreach ($summaryRows as $summaryRow) {
                if ($summaryRow->type == self::SUMMARY_TYPE) {
                    $coupon = $couponModel->find($summaryRow->row_id)->current();
                    if ($coupon == null) {
                        //IF this is a deprecated coupon - total value remains the same
                        continue;
                    }
                    if ($coupon->isMatched($detail->transform()) == false){
                        //IF this coupon is not matched any more - total value remains the same
                        continue;
                    }
                    //IF coupon is an actual and matched we need to recalculate the total discount
                    $summaryRow->total_amount = -$coupon->calculate($detail->transform());
                    $summaryRow->save();
                }
            }
        }
    }
    /**
     * Public constructor
     */
    public function  __construct() {
        $this->name = 'Coupons';
    }

    /**
     * This string is for rm_reservation_summary table
     */
    const SUMMARY_TYPE = 'coupons';

    /**
     * This method will invoke while adding new language to the Resmania
     *
     * @param string $iso ISO language code
     */
    public function addLanguage($iso)
    {
        parent::addLanguage($iso);
        $model = new RM_Coupons();
        $model->addLanguage($iso);
    }

    /**
     * Invokes after user delete language, make some changes for price module
     *
     * @param string $iso ISO language code
     * @return null
     */
    public function deleteLanguage($iso)
    {
        parent::deleteLanguage($iso);
        $model = new RM_Coupons();
        $model->deleteLanguage($iso);
    }

    /**
     * This method will return node object for main admin menu tree.
     * Every child classes could overload this method to return any of the node object.
     * If there is no need to present a plugin in the main admin tree overloaded method should return NULL
     *
     * @return stdClass | null
     */
    public function getNode(){
        $std = new stdClass;
        $std->id = $this->name.'_EditJson_NoAjax';
        $std->text = $this->getName();
        $std->leaf = 'true';
        $std->iconCls = 'RM_plugins_leaf_icon';
        return $std;
    }

    function getConfigNode(){
        return null;
    }

    public function install(){

        // *********
        // Languages
        // *********
        // add any non-base languages that are installed to the plugin
        $languageModel = new RM_Languages();
        $languages = $languageModel->fetchAllEnabled(); // get all installed languages
        $baseLanguages = array("en_GB","fr_FR"); // exclude array
        $db = Zend_Db_Table::getDefaultAdapter();

        foreach ($languages as $language) {
            if (!in_array($language->iso, $baseLanguages)){
                $db->query("ALTER TABLE `rm_coupons` ADD `".$language->iso."` TEXT NOT NULL");
            }
        }
    }
}
